package com.deepq.util;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.jgit.treewalk.filter.PathFilter;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * description: add a description [描述信息]
 *
 * @author : zp
 * @date 2024/4/19
 */
public class GitUtil {

    private static String localRootPath = "D:\\officeWork\\deepq\\tool-work";
    // git仓库地址
    private static String rpsUrl = "https://gitee.com/zpeter/zptest";
    //git分支名称
    private static String branchName = "master";
    // git项目名字
    private static String projectName = "sm4Util";
    //git登录名字
    private static String userName = "568849059@qq.com";
    //git登录密码
    private static String password = "zp@89218243";
    public static CredentialsProvider createCredential(String userName, String password) {
        return new UsernamePasswordCredentialsProvider(userName, password);
    }

    public static void main(String[] args) throws GitAPIException, IOException {
        // 初始化本地仓库，标记远程仓库地址 "https://gitee.com/xx/test.git"

        String localPath = "D:\\officeWork\\deepq\\tool-work\\sm4Util";
        String remotePath = "https://gitee.com/zpeter/zptest.git";
        String newBranchName = "newBranchName2";
//        Git git = Git.init().setDirectory(new File(localPath)).call();
//        StoredConfig config = git.getRepository().getConfig();
//        config.setString("remote", "origin", "url", remotePath);
//        config.save();
//        git.commit().setMessage("init").call();
//        //推到远程仓库
//        //1
        CredentialsProvider provider = createCredential("568849059@qq.com","zp@89218243");
//        git.push().setRemote("origin").setCredentialsProvider(provider)
//                .setRefSpecs(new RefSpec("master")).call();

      //  creatProject(remotePath,localPath,provider);
//        Git git = fromCloneRepository(remotePath,localPath,provider);
//        //2
//        commit(git,"test",provider);
//        //3
//        push(git,"dev",provider);
        //4
      //  getLogs()l

//        Repository repository = getRepositoryFromDir("D:\\\\SoftwareDev\\\\Code\\\\auto-cicd-store\\\\git-res");
//        List<String> logs = getLogs(repository);
//        System.out.println(logs);
        try {
            // 使用FileRepositoryBuilder来打开现有的仓库或创建一个新的仓库（如果它不存在）
//            Repository repository = new FileRepositoryBuilder()
//                    .setGitDir(new File(remotePath)) // 设置Git目录路径
//                    .readEnvironment() // scan environment GIT_* variables
//                    .findGitDir() // scan up the file system tree
//                    .build();

            Repository repository  = new FileRepository(getLocalPath() + "/.git");
            // 使用Git实例来操作仓库
            Git git = new Git(repository);

            // 将文件夹添加到暂存区（使用通配符模式匹配整个文件夹）
            git.add().addFilepattern(".").call(); // 调用add方法将更改添加到暂存区。这里使用匿名内部类定义了路径过滤器。

            // 创建新的分支（如果需要） - 注意：这将在当前分支上创建一个新分支，并切换到新分支。如果你已经在正确的分支上，可以省略这一步。
            git.branchCreate().setName(newBranchName).call(); // 创建新分支并切换到它。这里假设你已经在master或其他现有分支上。

            // 提交更改到新分支上。这里你可以提供一个提交信息。
            git.commit().setMessage("Commit message").call(); // 提交更改并设置提交信息。这里假设你已经添加了更改并切换到了新分支。
            //推送到远程
            git.push().setCredentialsProvider(provider).setForce(true).call();
            git.close();
        } catch (Exception e) {
            e.printStackTrace(); // 处理异常，例如文件不存在或权限问题等。在生产代码中，你可能想要更优雅地处理这些异常。
        }


    }


    public static void  creatProject(String remotePath,String localPath, CredentialsProvider provider) throws IOException, GitAPIException {
        // 指定仓库的路径，如果仓库不存在，JGit会自动创建它
        Git git = Git.open(new File(remotePath));

        File file = new File(localPath);
        git.add().addFilepattern(".").call();
        git.branchCreate().setName("new-branch-1").call();
        //提交
        git.commit().setMessage("仓库新分支").call();
        //推送到远程
        git.push().setCredentialsProvider(provider).setForce(true).call();
        git.close();

    }

    public static Git fromCloneRepository(String repoUrl, String cloneDir, CredentialsProvider provider) throws GitAPIException {
        Git git = Git.cloneRepository()
                .setCredentialsProvider(provider)
                .setURI(repoUrl)
                .setDirectory(new File(cloneDir)).call();
        return git;
    }
    public static Repository getRepositoryFromDir(String dir) throws IOException {
        return new FileRepositoryBuilder()
                .setGitDir(Paths.get(dir, ".git").toFile())
                .build();
    }
    public static void commit(Git git, String message, CredentialsProvider provider) throws GitAPIException {
        git.add().addFilepattern(".").call();
        git.commit()
                .setMessage(message)
                .call();
    }

    public static void push(Git git, CredentialsProvider provider) throws GitAPIException, IOException {
        push(git,null,provider);
    }

    public static void push(Git git, String branch, CredentialsProvider provider) throws GitAPIException, IOException {
        if (branch == null) {
            branch = git.getRepository().getBranch();
        }
        git.push()
                .setCredentialsProvider(provider)
                .setRemote("origin").setRefSpecs(new RefSpec(branch)).call();
    }

    public static List<String> getLogs(Repository repository) throws IOException {
        return getLogsSinceCommit(repository, null, null);
    }

    public static List<String> getLogsSinceCommit(Repository repository, String commit) throws IOException {
        return getLogsSinceCommit(repository, null, commit);
    }

    public static List<String> getLogsSinceCommit(Repository repository, String branch, String commit) throws IOException {
        if (branch == null) {
            branch = repository.getBranch();
        }
        Ref head = repository.findRef("refs/heads/" + branch);
        List<String> commits = new ArrayList<>();
        if (head != null) {
            try (RevWalk revWalk = new RevWalk(repository)) {
                revWalk.markStart(revWalk.parseCommit(head.getObjectId()));
                for (RevCommit revCommit : revWalk) {
                    if (revCommit.getId().getName().equals(commit)) {
                        break;
                    }
                    commits.add(revCommit.getFullMessage());
                    System.out.println("\nCommit-Message: " + revCommit.getFullMessage());
                }
                revWalk.dispose();
            }
        }

        return commits;
    }

    /**
     * 获取本地路径
     * @return
     */
    private static String getLocalPath(){
        return localRootPath + File.separator + projectName;
    }
}
